package graphics.datastructures.hierarchalbb;

import graphics.datastructures.BoundingBox;
import graphics.datastructures.Model;
import graphics.raytracing.CastResult;
import graphics.raytracing.Ray;
import graphics.raytracing.Tracable;

import java.util.Collection;
import java.util.Comparator;

public class HierarchalBoundingBox<T extends Tracable<? extends Tracable<T>>> implements Model<T> {
	/**
	 * 
	 */
	private static final long serialVersionUID = -8596728213704038149L;
	private Box<T> root;
	public HierarchalBoundingBox(Collection<T> tracables,BoundingBox<T> box)
	{
		root = new BoxBuilder<T>(tracables,box,100).build(); 
	}
	@Override
	public CastResult<T> cast(Ray ray) {
		return root.cast(ray);
	}
	@Override
	public float[][] getBB() {
		return root.getBB();
	}
	public static final Comparator<Tracable> xcomp = new Comparator<Tracable>() {

		@Override
		public int compare(Tracable o1, Tracable o2) {
			float x =o1.getBB()[0][0];
			float x1 = o2.getBB()[0][0];
			x=x-x1;
			if(x>0)
				return 1; 
			if(x<0)
				return -1;
			return 0;
		}
	};
	public static final Comparator<Tracable> ycomp = new Comparator<Tracable>() {

		@Override
		public int compare(Tracable o1, Tracable o2) {
			float x =o1.getBB()[0][1];
			float x1 = o2.getBB()[0][1];
			x=x-x1;
			if(x>0)
				return 1; 
			if(x<0)
				return -1;
			return 0;
		}
	};
	public static final Comparator<Tracable> zcomp = new Comparator<Tracable>() {

		@Override
		public int compare(Tracable o1, Tracable o2) {
			float x =o1.getBB()[0][2];
			float x1 = o2.getBB()[0][2];
			x=x-x1;
			if(x>0)
				return 1; 
			if(x<0)
				return -1;
			return 0;
		}
	};
	@Override
	public Collection<T> getTracables() {
		throw new IllegalAccessError("nope.");
	}
	public static Comparator<Tracable> getComp(XYZ d) {
		switch (d) {
		case X:
			return xcomp;
		case Y:
			return ycomp;
		case Z:
			return zcomp;
		}
		return null;
	}
	@Override
	public BoundingBox getBoundingBox() {
		return new BoundingBox(getBB());
	}
	
}
